<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue';
import { fetchMarketDataList } from '@/service/api/market-data';
import { fetchModelSetList } from '@/service/api/product-model-mapping';
import { fetchCurveConfigIdList } from '@/service/api/curve-config';
export interface Props {
  selectedTrialProduct?: ProductDetail | null;
  loading: boolean;
  trialProductDetail?: ProductDetail | null;
  trialCalculationLoading: boolean;
  trialData?: Record<string, any> | null;
  trialResult?: TrialResult | null;
  // 试算请求报文（由父组件传入，用于在模态框中展示 Request）
  trialRequest?: Record<string, any> | null;
}

type ProductDetail = {
  className: string;
  category: string;
  fields?: Array<{
    fieldName: string;
    fieldType: string;
    fullType: string;
    description: string;
  }>;
  description: string;
};

// 新增类型：试算结果载荷，兼容 request/response 以及指标字段
type TrialResultPayload = {
  request?: Record<string, any>;
  response?: any;
  npv?: number;
  pv01?: number;
  delta?: number;
  gamma?: number;
  theta?: number;
  vega?: number;
};

type TrialResult = {
  success: boolean;
  calculationTime?: string;
  result?: TrialResultPayload;
  error?: string;
};

// 定义visible双向绑定
const visible = defineModel<boolean>('visible');

const props = withDefaults(defineProps<Props>(), {
  selectedTrialProduct: null,
  trialProductDetail: null,
  trialData: null,
  trialResult: null,
  trialRequest: null
});

const emit = defineEmits<{
  (e: 'cancel'): void;
  (e: 'generateData'): void;
  (e: 'clearData'): void;
  (e: 'trialCalculation', marketDataId: string, mappingSetId?: string, curveSetId?: string): void;
  (e: 'updateTrialData', data: Record<string, any>): void;
}>();

// 市场数据相关
const selectedMarketData = ref<string>('');
const marketDataOptions = ref<Array<{ label: string; value: string }>>([]);

// 模型映射集相关
const selectedModelSet = ref<string>('');
const modelSetOptions = ref<Array<{ label: string; value: string }>>([]);

// 模型映射集相关
const selectedCurveSet = ref<string>('');
const curveSetOptions = ref<Array<{ label: string; value: string }>>([]);
// 删除重复的defineEmits调用

const handleCancel = () => {
  emit('cancel');
};

const handleGenerateData = () => {
  emit('generateData');
};

const handleTrialCalculation = () => {
  if (selectedMarketData.value) {
    emit('trialCalculation', selectedMarketData.value, selectedModelSet.value, selectedCurveSet.value);
  }
};

const handleMarketDataChange = (value: any) => {
  console.info(value);
  selectedMarketData.value = value || '';
};

const handleModelSetChange = (value: any) => {
  console.info('选择映射集:', value);
  selectedModelSet.value = value || '';
};
const handleCurveSetChange = (value: any) => {
  console.info('选择映射集:', value);
  selectedCurveSet.value = value || '';
};
const handleTrialDataChange = (e: Event) => {
  const target = e.target as HTMLTextAreaElement;
  try {
    const parsedData = JSON.parse(target.value);
    emit('updateTrialData', parsedData);
  } catch (error) {
    // 如果JSON格式不正确，暂时不更新数据
    console.warn('Invalid JSON format:', error);
  }
};

// 监听产品详情变化，如果模态框已打开且产品详情已加载，则自动生成数据
watch(
  () => props.trialProductDetail,
  (newDetail, oldDetail) => {
    if (visible.value && newDetail && !oldDetail && !props.trialData) {
      handleGenerateData();
    }
  }
);

// 获取市场数据列表
const loadMarketDataOptions = async () => {
  try {
    const { data: resData } = await fetchMarketDataList();
    console.info('市场数据列表:', resData);
    if (resData) {
      marketDataOptions.value = resData.map((item: any) => ({
        label: item.marketId,
        value: item.marketId
      }));
    }
  } catch (error) {
    console.error('获取市场数据列表失败:', error);
  }
};

// 获取模型映射集列表
const loadModelSetOptions = async () => {
  try {
    const { data: resData } = await fetchModelSetList();
    console.info('模型映射集列表:', resData);
    if (resData && Array.isArray(resData)) {
      modelSetOptions.value = resData.map((item: any) => ({
        label: item.name || item.id,
        value: item.id
      }));
    }
  } catch (error) {
    console.error('获取模型映射集列表失败:', error);
  }
};
// 获取曲线映射集列表
const loadCurveSetOptions = async () => {
  try {
    const { data: resData } = await fetchCurveConfigIdList();
    console.info('曲线映射集列表:', resData);
    if (resData && Array.isArray(resData)) {
      curveSetOptions.value = resData.map((item: any) => ({
        label: item,
        value: item
      }));
    }
  } catch (error) {
    console.error('获取曲线映射集列表失败:', error);
  }
};

// 组件挂载时加载选项
onMounted(() => {
  loadMarketDataOptions();
  loadModelSetOptions();
  loadCurveSetOptions();
});

// 监听模态框关闭状态，重置选择
watch(
  () => visible.value,
  newVisible => {
    if (!newVisible) {
      selectedMarketData.value = '';
      selectedModelSet.value = '';
    }
  }
);
// 函数注释：计算并生成用于展示的试算请求报文（优先使用父组件传入的 trialRequest，其次根据本地选择项与 trialData 组装）
const displayedRequest = computed(() => {
  if (props.trialRequest) return props.trialRequest;
  return {
    trade: props.trialData ?? {},
    marketDataId: selectedMarketData.value || '',
    mapSetId: selectedModelSet.value || '',
    curveSetId: selectedCurveSet.value || ''
  } as Record<string, any>;
});
</script>

<template>
  <AModal
    v-model:open="visible"
    :title="`产品试算 - ${props.selectedTrialProduct?.className || ''}`"
    width="1200px"
    :footer="null"
    :body-style="{ padding: '16px' }"
    @cancel="handleCancel"
  >
    <div v-if="props.loading" class="py-4 text-center">加载中...</div>
    <div v-else-if="props.trialProductDetail" class="trial-modal-container">
      <!-- 构造交易报文区域 -->
      <div class="mb-4">
        <ARow :gutter="16">
          <ACol :span="14">
            <h4 class="section-title">交易报文</h4>
            <div class="trial-data-display">
              <ATextarea
                :value="JSON.stringify(props.trialData, null, 2)"
                :rows="12"
                placeholder="交易报文数据"
                @change="handleTrialDataChange"
              />
            </div>
          </ACol>
          <ACol :span="10">
            <h4 class="section-title">估值参数集配置</h4>
            <ADescriptions :column="1" bordered size="small">
              <ADescriptionsItem label="市场数据集">
                <ASelect
                  v-model:value="selectedMarketData"
                  style="width: 100%"
                  :options="marketDataOptions"
                  @change="handleMarketDataChange"
                />
              </ADescriptionsItem>
              <ADescriptionsItem label="模型映射集:">
                <ASelect
                  v-model:value="selectedModelSet"
                  style="width: 100%"
                  :options="modelSetOptions"
                  allow-clear
                  @change="handleModelSetChange"
                />
              </ADescriptionsItem>
              <ADescriptionsItem label="曲线映射集:">
                <ASelect
                  v-model:value="selectedCurveSet"
                  style="width: 100%"
                  :options="curveSetOptions"
                  allow-clear
                  @change="handleCurveSetChange"
                />
              </ADescriptionsItem>
            </ADescriptions>
          </ACol>
        </ARow>
      </div>

      <!-- 选择模型进行试算区域 -->
      <div class="mb-4">
        <h4 class="section-title">选择模型进行试算</h4>
        <div class="trial-model-section">
          <!-- 数据集选择 - 并排布局 -->
          <div class="mb-4">
            <ARow :gutter="16"></ARow>
          </div>

          <div class="mb-4">
            <ASpace>
              <AButton
                type="primary"
                :loading="props.trialCalculationLoading"
                :disabled="!props.trialData || !selectedMarketData"
                @click="handleTrialCalculation"
              >
                <i class="carbon:calculator mr-1" />
                执行试算
              </AButton>
              <span class="text-gray-500">请先生成交易数据并选择市场数据集，模型映射集为可选项</span>
            </ASpace>
          </div>

          <!-- 试算结果 -->
          <div v-if="props.trialResult" class="mb-4">
            <h5>试算结果</h5>
            <ATabs default-active-key="response">
              <ATabPane key="request" tab="Request">
                <div class="trial-data-display">
                  <pre>{{ JSON.stringify(props.trialResult.result?.request ?? displayedRequest, null, 2) }}</pre>
                </div>
              </ATabPane>
              <ATabPane key="response" tab="Response">
                <div v-if="props.trialResult.success" class="trial-result-success">
                  <ATag color="success" class="mb-2 w-fit flex items-center">
                    <icon-carbon:checkmark-outline class="mr-1" />
                    成功
                  </ATag>
                  <div class="trial-data-display">
                    <pre>{{ JSON.stringify(props.trialResult.result?.response, null, 2) }}</pre>
                  </div>
                </div>
                <div v-else class="trial-result-error">
                  <ATag color="error" class="flex items-center">
                    <icon-carbon:close-outline class="mr-1" />
                    {{ `失败: ${props.trialResult.error}` }}
                  </ATag>
                </div>
              </ATabPane>
            </ATabs>
          </div>

          <!-- 加载状态 -->
          <div v-if="props.trialCalculationLoading" class="trial-loading">
            <ASpin size="large">
              <template #indicator>
                <i class="carbon:calculator" style="font-size: 24px" />
              </template>
            </ASpin>
            <p class="mt-2 text-center">正在执行试算...</p>
          </div>
        </div>
      </div>
    </div>
  </AModal>
</template>

<style scoped>
/* 基础工具类 */
.text-center {
  text-align: center;
}
.py-4 {
  padding: 16px 0;
}
.mb-4 {
  margin-bottom: 16px;
}
.mb-3 {
  margin-bottom: 12px;
}
.mb-2 {
  margin-bottom: 8px;
}
.mr-1 {
  margin-right: 4px;
}
.mt-2 {
  margin-top: 8px;
}
.text-gray-500 {
  color: #6b7280;
}

/* 布局组件样式 */
.trial-message-section,
.trial-model-section {
  background: #fafafa;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  padding: 16px;
}

.trial-data-display {
  background: #f6f8fa;
  border: 1px solid #e1e4e8;
  border-radius: 4px;
  padding: 12px;
  max-height: 200px;
  overflow-y: auto;
}

.trial-data-display pre {
  margin: 0;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 12px;
  line-height: 1.4;
  color: #24292e;
}

.section-title {
  margin: 0 0 12px 0;
  font-size: 16px;
  font-weight: 600;
  color: #262626;
}

.trial-modal-container {
  max-height: 70vh;
  overflow-y: auto;
}

.trial-result-success,
.trial-result-error {
  border-radius: 6px;
  padding: 12px;
}

.trial-result-success {
  background: #f6ffed;
  border: 1px solid #b7eb8f;
}

.trial-result-error {
  background: #fff2f0;
  border: 1px solid #ffccc7;
}

.trial-loading {
  text-align: center;
  padding: 40px 20px;
  background: #fafafa;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
}

/* 暗色主题适配 */
.dark .trial-message-section,
.dark .trial-model-section,
.dark .trial-loading {
  background: #2a2a2a;
  border-color: #404040;
}

.dark .trial-data-display {
  background: #1e1e1e;
  border-color: #404040;
}
.dark .trial-data-display pre {
  color: #e6e6e6;
}
.dark .section-title {
  color: #e6e6e6;
}
.dark .trial-result-success {
  background: #162312;
  border-color: #274916;
}
.dark .trial-result-error {
  background: #2a1215;
  border-color: #58181c;
}
</style>
